import { ComponentInstance } from 'vue'
import { Widget } from '../models'
import { WidgetType, DocData, PageData, SignData, SignOptions, WidgetSourceItem, WidgetSource } from '.'
import useZoom from '../components/contract/useZoom'
import useLayout from '../components/contract/useLayout'
import useTools from '../components/contract/useTools'
import useDocState from '../components/contract/useDocState'
import useDocScroll from '../components/contract/useDocScroll'
import useWidgetActive from '../components/contract/useWidgetActive'
import useWidgetSort from '../components/contract/useWidgetSort'
import useWidgetOperate from '../components/contract/useWidgetOperate'
import useWidgetValidate from '../components/contract/useWidgetValidate'
import useWidgetSource from '@/components/contract/useWidgetSource'
import useSelection from '../components/contract/useSelection'

/** 文档查看 FaContract 组件实例 */
export interface Viewer
  extends ComponentInstance,
    ReturnType<typeof useWidgetActive>,
    ReturnType<typeof useWidgetSort>,
    ReturnType<typeof useWidgetOperate>,
    ReturnType<typeof useWidgetValidate> {
  /**
   * 文档展示
   */

  /** 文档列表 - 用于批量文档 */
  docs: DocData[]

  /** 当前文档 */
  doc: DocData

  /** 当前文档索引，需要 `.sync` 双向同步 */
  docIndex: number

  /**
   * 页面图片地址
   * @description 如果文档页面数据 `PageData` 未设置 `src`，则可使用该选项统一设置文档图片地址
   * @version v1.4.0
   */
  pageSrc?: (doc: DocData, page: PageData) => string | void

  /**
   * 页面 HTML 内容
   * @description 如未设置页面图片，可使用该方法设置每页 HTML 内容，支持异步
   */
  pageHtml?: (doc: DocData, page: PageData) => string | Promise<string> | void

  /** 页面上下间距 */
  pageSpacing: number

  /** 是否开启工具栏 */
  toolbar: boolean

  /** 工具栏缩放级别列表 */
  zoomLevels: number[]

  /** 滚动节点 */
  scroller: HTMLElement | null

  /**
   * 控件配置
   */

  /** 是否启用控件 */
  widget: boolean

  /** 控件列表 */
  widgets: Widget[]

  /** 是否允许拖入控件 */
  droppable: boolean

  /** 控件自定义类名 */
  widgetClassName?: (widget: Widget) => string | void

  /** 控件自定义提示 */
  widgetTips?: (widget: Widget) => string | void

  /** 控件是否支持跨页拖动（仅限普通控件，骑缝和批量控件不允许跨页拖动） */
  widgetMovingAcrossPages: boolean

  /** 控件名称是否必填 */
  widgetNameRequired: boolean | ((widget: Widget) => boolean)

  /** 控件参与方是否必须选择 */
  widgetActorRequired: boolean | ((widget: Widget) => boolean)

  /** 控件数据来源 */
  widgetSources?: (widget: Widget) => WidgetSourceItem[]

  /** 控件数据来源加载 */
  widgetSourceLoader?: (widgets: Widget[]) => Promise<Record<WidgetSource | string, string> | void>

  /** 控件数据来源是否自动加载 */
  widgetSourceAutoLoad: boolean

  /** 控件拖入前，可返回 `Promise.reject` 阻止 */
  beforeWidgetDrop?: (widget: Widget) => void

  /** 控件删除前，可返回 `Promise.reject` 阻止 */
  beforeWidgetRemove?: (...widgets: Widget[]) => void

  /**
   * 签署控件
   */

  /**
   * 签章配置选项
   * @description 可配置日期章图片地址、日期章全局配置、签章全局切换、签章自定义 class 等
   * @version v1.4.0
   */
  signOptions: SignOptions

  /** 是否启用骑缝控件 */
  riding: boolean

  /** 骑缝控件列表(包含所有文档) */
  ridings: Widget[]

  /** 当前文档骑缝控件列表 */
  docRidings: Widget[]

  /** 骑缝区域宽度 (px) */
  ridingWidth: number

  /** 允许的骑缝控件类型 */
  allowedRidingTypes: WidgetType[]

  /** 批量控件列表(包含所有文档) */
  batches: Widget[]

  /** 签名列表 - 用于签名切换 */
  signatures: SignData[]

  /** 印章列表 - 用于印章切换 */
  seals: SignData[]

  /** 切换签章前，可返回 `Promise.reject` 阻止 */
  beforeSignChange?: (widget: Widget, sign: SignData) => void

  /**
   * 填写控件
   */

  /** 附件上传方法 */
  attachmentUpload?: (file: File, widget: Widget) => Promise<{ id: string; fileName: string }>

  /** 附件接受上传的文件类型 */
  attachmentAccept?: string

  /** 图片控件上传方法 */
  imageUpload?: (file: File, widget: Widget) => Promise<{ id: string; name?: string; src?: string }>

  /** 图片控件接受上传的文件类型 */
  imageAccept?: string

  /**
   * 图片控件地址
   * @description 如果图片控件为设置 `image.src`，则可使用该选项统一设置图片控件地址
   */
  imageSrc?: (widget: Widget) => string | void

  /**
   * 图片上传前是否裁剪
   */
  imageCrop: boolean

  /**
   * 其他
   */

  /** 状态 */
  state: ReturnType<typeof useDocState>

  /** 滚动 */
  scroll: ReturnType<typeof useDocScroll>

  /** 缩放 */
  zoom: ReturnType<typeof useZoom>

  /** 布局 */
  layout: ReturnType<typeof useLayout>

  /** 工具区域 */
  tools: ReturnType<typeof useTools>

  /** 控件数据来源 */
  source: ReturnType<typeof useWidgetSource>

  /** 控件选择 */
  selection: ReturnType<typeof useSelection>
}
